package com.dure.commonlib.util;

import android.text.TextUtils;

import com.socks.library.KLog;

import org.xutils.DbManager;
import org.xutils.common.util.KeyValue;
import org.xutils.db.sqlite.WhereBuilder;
import org.xutils.ex.DbException;
import org.xutils.x;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by leix on 8/14/16.
 */
public class DbUtils {
    static DbUtils dbUtils;
    DbManager db;

    public static DbUtils getInstance() {
        if (dbUtils == null) {
            dbUtils = new DbUtils();
        }

        return dbUtils;
    }

    private DbUtils() {
        DbManager.DaoConfig daoConfig = new DbManager.DaoConfig()
                .setDbName("hotmemory.db")
                // 不设置dbDir时, 默认存储在app的私有目录.
//                .setDbDir(new File("/sdcard")) // "sdcard"的写法并非最佳实践, 这里为了简单, 先这样写了.
                .setDbVersion(2)
                .setDbOpenListener(new DbManager.DbOpenListener() {
                    @Override
                    public void onDbOpened(DbManager db) {
                        // 开启WAL, 对写入加速提升巨大
                        db.getDatabase().enableWriteAheadLogging();
                    }
                })
                .setDbUpgradeListener(new DbManager.DbUpgradeListener() {
                    @Override
                    public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
                        // TODO: ...
                        // db.addColumn(...);
                        // db.dropTable(...);
                        // ...
                        // or
                        // db.dropDb();
                    }
                });

        db = x.getDb(daoConfig);
    }

    public <T> void addColumn(Class<T> clazz, String columnName) {
        try {
            db.addColumn(clazz, columnName);
        } catch (DbException e) {
            e.printStackTrace();
        }
    }

    public <T> void insertItem(T t) {

        try {
//            db.save(t);
            db.saveBindingId(t);
//            db.saveOrUpdate(t);
//            db.saveOrUpdate(t);

        } catch (DbException e) {
            e.printStackTrace();
        }
    }

    public <T> void saveOrUpdateItem(T t) {
        try {
            db.saveOrUpdate(t);
        } catch (DbException e) {
            e.printStackTrace();
        }
    }

    public <T> int deleteItem(Class<T> clazz, WhereBuilder builder) {
        int result = -1;
        try {
            result = db.delete(clazz, builder);
        } catch (DbException e) {
            e.printStackTrace();
        }
        return result;
    }



    public <T> List<T> getAll(Class<T> clazz) {
        return getAll(clazz, "");
    }

    public <T> List<T> getAll(Class<T> clazz, WhereBuilder where) {
        return getAll(clazz, where, "");
    }

    public <T> List<T> getAll(Class<T> clazz, String orderKey) {
        return getAll(clazz, null, orderKey, false);
    }

    public <T> List<T> getAll(Class<T> clazz, String orderKey, boolean desc) {
        return getAll(clazz, null, orderKey, desc);
    }

    public <T> List<T> getAll(Class<T> clazz, WhereBuilder where, String orderKey) {
        return getAll(clazz, where, orderKey, false);
    }

    public <T> List<T> getAll(Class<T> clazz, WhereBuilder where, String orderKey, boolean desc) {
        List<T> list = null;
        try {
//            list = db.selector(clazz).where("parent_name", "=", where).orderBy("index", desc).findAll();
            if (!TextUtils.isEmpty(orderKey))
                list = db.selector(clazz).where(where).orderBy(orderKey, desc).findAll();
            else if (where != null) {
                list = db.selector(clazz).where(where).findAll();
            } else {
                list = db.selector(clazz).findAll();
            }
        } catch (DbException e) {
            e.printStackTrace();
        }

        if (list == null)
            list = new ArrayList<T>();

        return list;
    }

    public <T> T getItem(Class<T> clazz, String value) {
        T t = null;
        try {
            t = db.selector(clazz).where("name", "=", value).findFirst();
        } catch (DbException e) {
            e.printStackTrace();
        }

        return t;
    }

    public <T> boolean containItem(Class<T> clazz, WhereBuilder whereBuilder) {
        if (getItem(clazz, whereBuilder) != null) {
            return true;
        }
        return false;
    }

    public <T> T getItem(Class<T> clazz, WhereBuilder whereBuilder) {
        T t = null;
        try {
            t = db.selector(clazz).where(whereBuilder).findFirst();
        } catch (DbException e) {
            e.printStackTrace();
        }

        return t;
    }

    public <T> void updateItem(Class<T> clazz, WhereBuilder builder, KeyValue... keyValues) {
        try {
            int updateResult = db.update(clazz, builder, keyValues);
            KLog.d("lesleixz", "update result = " + updateResult);
        } catch (DbException e) {
            e.printStackTrace();
        }
    }

    public <T> void updateItem(T t, String... updateColumnNames) {
        try {
            db.update(t, updateColumnNames);
        } catch (DbException e) {
            e.printStackTrace();
        }
    }

}
